﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Text;
using Wheeler.Web.ViewModels;
using Wheeler.Common.Extensions;

namespace Wheeler.Web.Utility
{
    public static class HtmlHelpers
    {
        /// <summary>
        /// Custom helper method that renders a Warning Message Box based on BootStrap alert
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static MvcHtmlString WarningMessageBox(this HtmlHelper helper, String message, String heading = null)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"alert alert-block\">");
            sb.Append("<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>");
            sb.AppendFormat("<h4>{0}</h4>", heading.IsNullOrEmpty() ? "Warning!" : heading);
            sb.AppendFormat(message);                  
            sb.Append("</div>");
            return MvcHtmlString.Create(sb.ToString());
        }

        /// <summary>
        /// Custom helper method that renders a Error Message Box based on BootStrap alert
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static MvcHtmlString ErrorMessageBox(this HtmlHelper helper, string message, String heading = null)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"alert alert-error\">");
            sb.Append("<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>");
            sb.AppendFormat("<h4>{0}</h4>", heading.IsNullOrEmpty() ? "Error!" : heading);
            sb.AppendFormat(message);
            sb.Append("</div>");
            return MvcHtmlString.Create(sb.ToString());
        }

        /// <summary>
        /// Custom helper method that renders a Success Message Box based on BootStrap alert
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static MvcHtmlString SuccessMessageBox(this HtmlHelper helper, string message, String heading = null)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"alert alert-success\">");
            sb.Append("<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>");
            sb.AppendFormat("<h4>{0}</h4>", heading.IsNullOrEmpty() ? "Success!" : heading);
            sb.AppendFormat(message);
            sb.Append("</div>");
            return MvcHtmlString.Create(sb.ToString());
        }

        /// <summary>
        /// Custom helper method that renders a Info Message Box based on BootStrap alert
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static MvcHtmlString InfoMessageBox(this HtmlHelper helper, string message, String heading = null)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div class=\"alert alert-info\">");
            sb.Append("<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>");
            sb.AppendFormat("<h4>{0}</h4>", heading.IsNullOrEmpty() ? "Success!" : heading);
            sb.AppendFormat(message);
            sb.Append("</div>");
            return MvcHtmlString.Create(sb.ToString());    
        }

        /// <summary>
        /// Gets Formatted Page Title
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="title"></param>
        /// <returns></returns>
        public static String GetPageTitle(this HtmlHelper helper, string title)
        {
            //return string.Format(".:JobBoard:. {0}", title);
            return String.Format("{0} - {1}", title, ConfigReader.SiteName);
        }

        /// <summary>
        /// Creates a Script Tag for Java Script file
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="scriptName"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static MvcHtmlString JavaScript(this HtmlHelper helper, string scriptName, UrlHelper url)
        {
            String scriptPath = url.Content(String.Format("~/Scripts/{0}", scriptName));
            return MvcHtmlString.Create(String.Format("<script src=\"{0}\" type=\"text/javascript\"></script>", scriptPath));
        }
        
        /// <summary>
        /// Creates an Action Link tag <a></a> for Administrator Area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="linkText"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static MvcHtmlString AdminLink(this HtmlHelper helper, String linkText, String action, String controllerName, object htmlAttributes = null)
        {
            return helper.ActionLink(linkText, action, controllerName, new { area = AppConstants.Area.ADMIN }, htmlAttributes);
        }
        /// <summary>
        /// Creates an Action Link tag <a></a> for Private Area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="linkText"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static MvcHtmlString PrivateLink(this HtmlHelper helper, String linkText, String action, String controllerName, object htmlAttributes = null)
        {            
            return helper.ActionLink(linkText, action, controllerName, new { area = AppConstants.Area.PRIVATE }, htmlAttributes);
        }
       
        /// <summary>
        /// Creates an Action Link for Public Area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="linkText"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static MvcHtmlString PublicLink(this HtmlHelper helper, String linkText, String action, String controllerName, object htmlAttributes = null)
        {
            return helper.ActionLink(linkText, action, controllerName, new { area = AppConstants.Area.PUBLIC }, htmlAttributes);
        }
        /// <summary>
        /// Creates a relative URL for Private area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static String PrivateUrl(this UrlHelper helper, String action, String controllerName)
        {
            return helper.Action(action, controllerName, new { area = AppConstants.Area.PRIVATE });
        }

        /// <summary>
        /// Creates a relative URL for JobSeeker area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static String JobSeekerUrl(this UrlHelper helper, String action, String controllerName)
        {
            return helper.Action(action, controllerName, new { area = AppConstants.Area.JOB_SEEKER });
        }

        /// <summary>
        /// Creates a relative URL for Admin area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static String AdminUrl(this UrlHelper helper, String action, String controllerName)
        {
            return helper.Action(action, controllerName, new { area = AppConstants.Area.ADMIN });
        }
        /// <summary>
        /// Creates a relative URL for Public area
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public static String PublicUrl(this UrlHelper helper, String action, String controllerName)
        {
            return helper.Action(action, controllerName, new { area = AppConstants.Area.PUBLIC });
        }

        /// <summary>
        /// Builds the icon URL based on document type
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String GetFileTypeIconUrl(this UrlHelper helper, String fileName)
        {
            String extension = System.IO.Path.GetExtension(fileName);
            String icon = "txt-icon.png";
            if (!extension.IsNullOrEmpty())
            {
                if (String.Compare(extension.ToLower(), ".docx", true) == 0)
                    icon = "word-icon.png";
                else if (String.Compare(extension.ToLower(), ".pdf", true) == 0)
                    icon = "pdf-icon.png";
            }
            return String.Format("/Content/Images/{0}", icon);            
        }

        ///// <summary>
        ///// Creates a Job Details link for a job
        ///// </summary>
        ///// <param name="helper"></param>
        ///// <param name="jobID"></param>
        ///// <param name="jobUrlName"></param>
        ///// <returns></returns>
        //public static String JobDetailsUrl(this UrlHelper helper, int jobID, String jobUrlName, String companyKey = null, bool includeDomainAddress = false)
        //{
        //    String domain = includeDomainAddress ? WebUtil.GetDomainAddress() : String.Empty;
        //    if(companyKey.IsEmpty())
        //        return String.Format("{0}/job/details/{1}/{2}", domain, jobID, jobUrlName);

        //    return String.Format("{0}/{1}/{2}/{3}", domain, companyKey, jobID, jobUrlName);
        //}
        ///// <summary>
        ///// Creates a Product Details Link according to product info
        ///// </summary>
        ///// <param name="helper"></param>
        ///// <param name="productID"></param>
        ///// <param name="productUrl"></param>
        ///// <param name="linkText"></param>
        ///// <returns></returns>
        //public static MvcHtmlString ProductDetailsLink(this HtmlHelper helper, int productID, String productUrl, String linkText)
        //{
        //    return new MvcHtmlString(String.Format("<a href=\"/product/details/{0}/{1}\">{2}</a>", productID, productUrl, linkText));
        //}

        ///// <summary>
        ///// Creates Company Address Html to Show in the Company Profile Page
        ///// </summary>
        ///// <param name="helper"></param>
        ///// <param name="address"></param>
        ///// <param name="district"></param>
        ///// <param name="country"></param>
        ///// <param name="phone"></param>
        ///// <param name="fax"></param>
        ///// <param name="email"></param>
        ///// <param name="web"></param>
        ///// <returns></returns>
        //public static MvcHtmlString BuildCompanyAddress(this HtmlHelper helper, String address, String district, String country, String phone, String fax, String email, String web)
        //{
        //    StringBuilder sb = new StringBuilder(10);
        //    sb.AppendFormat("{0}", address.HtmlEncode());
        //    sb.AppendFormat("{0}{1}, {2}", address.IsEmpty() ? String.Empty : "<br/>", district.HtmlEncode(), country.HtmlEncode());
        //    if(!phone.IsEmpty())
        //        sb.AppendFormat("<br />Phone: {0}", phone.HtmlEncode());
        //    if (!fax.IsEmpty())
        //        sb.AppendFormat("Fax: {0}", phone.IsEmpty() ? "<br/>" : ", ", fax.HtmlEncode());
        //    if (!email.IsEmpty())
        //        sb.AppendFormat("<br />Email: {0}", email.HtmlEncode());
        //    if (!web.IsEmpty())
        //        sb.AppendFormat("<br/>Web Site: <a href='{0}' target='_blank'>{0}</a>", WebUtil.GetCompleteUrl(web));

        //    return MvcHtmlString.Create(sb.ToString());
        //}

        #region Private Methods
        
        //public static string GetCategoryListLink(String categoryName)
        //{
        //    return String.Format("/product/category/{0}", categoryName.ToSeoUrl());
        //}
        /// <summary>
        /// Gets Formated Data for Display Purpose
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static String FormatData(this HtmlHelper helper, object data)
        {
            return WebUtil.FormatData(data);
        }

        ///// <summary>
        ///// Gets Resume Download Url
        ///// </summary>
        ///// <param name="jobSeekerID"></param>
        ///// <param name="fileName"></param>
        ///// <returns></returns>
        //public static String ResumeDownloadUrl(this UrlHelper url, int resumeID)
        //{
        //    //return String.Format("{0}/{1}/{2}", AppConstants.Directories.RESUMES, jobSeekerID, fileName);
        //    return String.Format("{0}/{1}", url.PublicUrl("DownloadResume", "FileDownload"), resumeID);
        //}
        
        ///// <summary>
        ///// Creates Category Breadcrumb for a Given Category ID
        ///// </summary>
        ///// <param name="helper"></param>
        ///// <param name="categoryID"></param>
        ///// <param name="buildLink"></param>
        ///// <returns></returns>
        //public static MvcHtmlString GetCategoryBreadCrumb(this HtmlHelper helper, int categoryID, bool buildLink = false)
        //{
        //    if (categoryID > 0)
        //    {                
        //        CategoryViewModel category = ApplicationCache.Categories.FirstOrDefault(P => P.ID == categoryID);
        //        if (category != null)
        //        {
        //            List<String> names = new List<String>();
        //            names.Add(category.Name);
        //            while (category.ParentCategory != null)
        //            {
        //                names.Add(category.ParentCategory.Name);
        //                category = category.ParentCategory;
        //            }
        //            StringBuilder sb = new StringBuilder(10);
        //            for (int i = names.Count - 1; i >= 0; i--)
        //            {
        //                String format = " -> {0}";
        //                if (sb.Length == 0)
        //                    format = "{0}";

        //                sb.AppendFormat(format, buildLink ?
        //                    helper.ActionLink(names[i], "category", "job", new { area = AppConstants.Area.PUBLIC, id = names[i].ToSeoUrl() }, null).ToHtmlString()
        //                    : names[i]);
        //            }
        //            return MvcHtmlString.Create(sb.ToString());
        //        }
        //    }
        //    return null;
        //}

        //public static MvcHtmlString SelectableCategoryList(this HtmlHelper helper, List<Wheeler.Web.ViewModels.CategoryViewModel> categories, bool addSelectionRadioForAllParents, int selectedCategory = 0, bool includeChildCategories = true)
        //{
        //    if (categories == null || categories.Count == 0)
        //        return null;
        //    StringBuilder sb = new StringBuilder();
        //    List<CategoryViewModel> parentCategories = (from P in categories where P.ParentID == null select P).ToList();
        //    int rowCounter = 0;
        //    bool hasColumnClosed = true;
        //    foreach (CategoryViewModel parentCategory in parentCategories)
        //    {
        //        if (rowCounter > 0 && rowCounter % ConfigReader.NumberOfRowsInCategorySelection == 0)
        //        {
        //            sb.Append("</div>");
        //            hasColumnClosed = true;
        //            rowCounter = 0;
        //        }
        //        if (rowCounter == 0)
        //        {
        //            sb.AppendFormat("<div class='category-column'><div class='parent-category' style='margin-top:0px;'>");
        //            hasColumnClosed = false;
        //        }
        //        else
        //            sb.Append("<div class='parent-category'>");
        //        if (addSelectionRadioForAllParents)
        //        {
        //            if (selectedCategory == parentCategory.ID)
        //                sb.AppendFormat("<input checked='checked' name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}'/> <label for='rdnCategory_{0}'>{1}</label>", parentCategory.ID, parentCategory.Name);
        //            else
        //                sb.AppendFormat("<input name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}'/> <label for='rdnCategory_{0}'>{1}</label>", parentCategory.ID, parentCategory.Name);
        //            //sb.AppendFormat();
        //        }
        //        else
        //            sb.AppendFormat("{0}", parentCategory.Name);
        //        sb.Append("</div>");
        //        rowCounter++;
        //        if (rowCounter % ConfigReader.NumberOfRowsInCategorySelection == 0)
        //        {
        //            sb.Append("</div>");
        //            hasColumnClosed = true;
        //            rowCounter = 0;
        //        }
        //        //var firstLevelChildren = from P in ApplicationCache.Categories where P.ParentID == parentCategory.ID && P.PropertyDefinition.IsNullOrEmpty() select P;
        //        //foreach (CategoryViewModel firstLevelChild in firstLevelChildren)
        //        //{
        //            //if (rowCounter > 0 && rowCounter % ConfigReader.NumberOfRowsInCategorySelection == 0)
        //            //{
        //            //    sb.Append("</div>");
        //            //    hasColumnClosed = true;
        //            //    rowCounter = 0;
        //            //}
        //            //if (rowCounter == 0)
        //            //{
        //            //    sb.AppendFormat("<div class='category-column'><div class='first-child'>");
        //            //    hasColumnClosed = false;
        //            //}
        //            //else
        //            //    sb.Append("<div class='first-child'>");
        //            //if (addSelectionRadioForAllParents)
        //            //{
        //            //    if (selectedCategory == firstLevelChild.ID)
        //            //        sb.AppendFormat("<input checked='checked' name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}'/><label for='rdnCategory_{0}'>{1}</label>", firstLevelChild.ID, firstLevelChild.Name);
        //            //    else
        //            //        sb.AppendFormat("<input name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}'/><label for='rdnCategory_{0}'>{1}</label>", firstLevelChild.ID, firstLevelChild.Name);
        //            //}
        //            //else
        //            //    sb.AppendFormat("{0}", firstLevelChild.Name);
        //            //sb.Append("</div>");
        //            //rowCounter++;
        //            //if (rowCounter % ConfigReader.NumberOfRowsInCategorySelection == 0)
        //            //{
        //            //    sb.Append("</div>");
        //            //    hasColumnClosed = true;
        //            //    rowCounter = 0;
        //            //}
        //            var secondLevelChildren = from P in ApplicationCache.Categories where P.ParentID == parentCategory.ID select P;
        //            //if (!addSelectionRadioForAllParents)
        //            if(includeChildCategories)
        //            {
        //                foreach (CategoryViewModel secondLevelChild in secondLevelChildren)
        //                {
        //                    if (rowCounter == 0)
        //                    {
        //                        sb.AppendFormat("<div class='category-column'>");
        //                        hasColumnClosed = false;
        //                    }
        //                    sb.AppendFormat("<div class='jb-second-child'>");
        //                    ///Product Cannot be entered under an empty category definition
        //                    //if (secondLevelChild.PropertyDefinition.IsNullOrEmpty())
        //                    //    sb.AppendFormat(secondLevelChild.Name);
        //                    if (selectedCategory == secondLevelChild.ID)
        //                        sb.AppendFormat("<input name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}' checked='checked'/> <label for='rdnCategory_{0}'>{1}</label>", secondLevelChild.ID, secondLevelChild.Name);
        //                    else
        //                        sb.AppendFormat("<input name='rdnCategory' id='rdnCategory_{0}' type='radio' value='{0}'/> <label for='rdnCategory_{0}'>{1}</label>", secondLevelChild.ID, secondLevelChild.Name);
        //                    sb.Append("</div>");
        //                    rowCounter++;
        //                    if (rowCounter % ConfigReader.NumberOfRowsInCategorySelection == 0)
        //                    {
        //                        sb.Append("</div>");
        //                        hasColumnClosed = true;
        //                        rowCounter = 0;
        //                    }
        //                }
        //            }
        //        //}
        //    }
        //    if (!hasColumnClosed)
        //        sb.Append("</div>");
        //    return new MvcHtmlString(sb.ToString());
        //}      

        #endregion Private Methods

        #region ViewData Extensions
        /// <summary>
        /// An extension to viewdata to determine whether there is any data saved notification or not
        /// </summary>
        /// <param name="viewData"></param>
        /// <returns></returns>
        public static bool HasSaved(this ViewDataDictionary viewData)
        {
            return viewData[AppConstants.ViewDataKeys.SAVED] == null ? false : Wheeler.Common.DB.NullHandler.GetBoolean(viewData[AppConstants.ViewDataKeys.SAVED]);
        }
        #endregion
    }
}